

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
    <meta name="description" content="@[TOC] 参考资料 软件设计模式概述 Java 设计模式 已完结（IDEA 2022.1最新版）4K蓝光画质+杜比音效 一、适配器模式 Adapter 定义：将一个类的接口转换成用户希望的另一种接口，解决不同类接口不兼容的问题。分类：  类适配器模式 对象适配器模式  适配器模式主要有以下几个主要角色：  目标 （Target）接口：当前系统业务所需要的接口，可以是 abstract clas">
<meta property="og:type" content="article">
<meta property="og:title" content="设计模式 笔记2 _ 七个结构型模式 _ 适配器模式 _ 桥接模式 _ 装饰器模式 _ 组合模式 _ 代理模式_ 外观模式 _ 享元模式 _模板代码、优缺点、应用场景总结 _ 基于Java实现">
<meta property="og:url" content="http://example.com/2022/08/11/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20%E7%AC%94%E8%AE%B02%20_%20%E4%B8%83%E4%B8%AA%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F%20_%20%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F%20_%20%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F%20_%20%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%20_%20%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%20_%20%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F_%20%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F%20_%20%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%20_%E6%A8%A1%E6%9D%BF%E4%BB%A3%E7%A0%81%E3%80%81%E4%BC%98%E7%BC%BA%E7%82%B9%E3%80%81%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E6%80%BB%E7%BB%93%20_%20%E5%9F%BA%E4%BA%8EJava%E5%AE%9E%E7%8E%B0/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="@[TOC] 参考资料 软件设计模式概述 Java 设计模式 已完结（IDEA 2022.1最新版）4K蓝光画质+杜比音效 一、适配器模式 Adapter 定义：将一个类的接口转换成用户希望的另一种接口，解决不同类接口不兼容的问题。分类：  类适配器模式 对象适配器模式  适配器模式主要有以下几个主要角色：  目标 （Target）接口：当前系统业务所需要的接口，可以是 abstract clas">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2022-08-11T01:41:56.000Z">
<meta property="article:modified_time" content="2022-08-22T15:41:21.743Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="设计模式">
<meta name="twitter:card" content="summary_large_image">
  
  
  
  <title>设计模式 笔记2 _ 七个结构型模式 _ 适配器模式 _ 桥接模式 _ 装饰器模式 _ 组合模式 _ 代理模式_ 外观模式 _ 享元模式 _模板代码、优缺点、应用场景总结 _ 基于Java实现 - Hexo</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.9.2","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.2.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>尤 Ni&#39;s Blog</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="设计模式 笔记2 _ 七个结构型模式 _ 适配器模式 _ 桥接模式 _ 装饰器模式 _ 组合模式 _ 代理模式_ 外观模式 _ 享元模式 _模板代码、优缺点、应用场景总结 _ 基于Java实现"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        John Doe
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2022-08-11 09:41" pubdate>
          2022年8月11日 上午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          24k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          198 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">设计模式 笔记2 _ 七个结构型模式 _ 适配器模式 _ 桥接模式 _ 装饰器模式 _ 组合模式 _ 代理模式_ 外观模式 _ 享元模式 _模板代码、优缺点、应用场景总结 _ 基于Java实现</h1>
            
              <p class="note note-info">
                
                  
                    本文最后更新于：1 小时前
                  
                
              </p>
            
            
              <div class="markdown-body">
                
                <p>@[TOC]</p>
<h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><hr>
<p><a target="_blank" rel="noopener" href="http://c.biancheng.net/view/1371.html">软件设计模式概述</a></p>
<p><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1u3411P7Na?p=20">Java 设计模式 已完结（IDEA 2022.1最新版）4K蓝光画质+杜比音效</a></p>
<h1 id="一、适配器模式-Adapter"><a href="#一、适配器模式-Adapter" class="headerlink" title="一、适配器模式 Adapter"></a>一、适配器模式 Adapter</h1><hr>
<p>定义：将一个类的接口转换成用户希望的另一种接口，解决不同类接口不兼容的问题。<br>分类：</p>
<ul>
<li>类适配器模式</li>
<li>对象适配器模式</li>
</ul>
<p>适配器模式主要有以下几个主要角色：</p>
<ul>
<li>目标 （Target）接口：当前系统业务所需要的接口，可以是 abstract class 或 interface</li>
<li>适配者（Adaptee）类：它是被访问和适配的现存组件库中的组件接口</li>
<li>适配器（Adapter）类：是一个转换器，通过继承或引用现存组件库中的组件接口，让用户按目标接口的格式访问 Adaptee</li>
</ul>
<p>优点：</p>
<ul>
<li>客户端通过适配器可透明调用目标接口</li>
<li>复用已有的类，不用修改原来的代码而重用现有的适配者类</li>
<li>将目标类和适配者类解耦，解决了目标类和适配者类接口不一致的问题</li>
<li>在很多业务场景中符合开闭原则</li>
</ul>
<p>缺点：</p>
<ul>
<li>适配器编写过程需结合业务考虑，会增加系统复杂性</li>
<li>增加了代码阅读难度，降低了代码可读性</li>
</ul>
<h2 id="1-1-类适配器"><a href="#1-1-类适配器" class="headerlink" title="1.1 类适配器"></a>1.1 类适配器</h2><p>模板代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//目标接口</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Target</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">//适配者: 负责定义要执行的业务</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Adaptee</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">specificRequest</span><span class="hljs-params">()</span><br>    &#123;<br>        System.out.println(<span class="hljs-string">&quot;适配者中的业务代码被调用！&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">//适配器类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ClassAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Adaptee</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Target</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span><br>    &#123;<br>        specificRequest();<br>    &#125;<br>&#125;<br><span class="hljs-comment">//客户端代码</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span><br>    &#123;<br>        System.out.println(<span class="hljs-string">&quot;类适配器模式测试：&quot;</span>);<br>        <span class="hljs-type">Target</span> <span class="hljs-variable">target</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ClassAdapter</span>();<br>        target.request();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>【应用实例】<br>接下来以生活中的实例来实现适配器模式：<br>对于大多数商务本来说，为了达到轻薄的目的，往往会缺少一些插口，比如笔者的电脑就没有宽带网线RJ45的插口，要想通过网线连接宽带，只能在 USB接口上插入一个 Type-C 拓展坞 ，然后在将网线RJ45接口插入到Type-C拓展坞，接下来就使用代码来模拟这一功能。<br>首先定义普通的 USB 接口，以及一个USB 接口实现类，表示具体的 USB 品牌</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// USB 类型 -&gt; Target 目标接口</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">USB</span>&#123;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">()</span>;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">disconnect</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 某个品牌的 USB</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">USBImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">USB</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;USB 连接成功!&quot;</span>);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">disconnect</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;USB 已断开连接&quot;</span>);<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<p>同理，定义普通的Rj45网线接口，以及一个Rj45接口实现类，表示具体的 Rj45 品牌</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// Rj45 类型</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Rj45</span>&#123;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">()</span>;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">disconnect</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 某个品牌的 Rj45</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Rj45Impl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Rj45</span>&#123;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;Rj45 连接成功&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">disconnect</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;Rj45 已断开.&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<pre><code class="hljs">接下来设计一个简单的电脑类，电脑只有一个USB接口：
</code></pre>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Computer</span>&#123;<br>    USB usb;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Computer</span><span class="hljs-params">(USB usb)</span>&#123;<br>        <span class="hljs-built_in">this</span>.usb = usb;<br>    &#125;<br>    <span class="hljs-comment">// 插入USB接口</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">(USB newUsb)</span>&#123;<br>        <span class="hljs-built_in">this</span>.usb.connect();<br>        newUsb.connect();<br>    &#125;<br>    <span class="hljs-comment">// 断开USB的接口</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">discount</span><span class="hljs-params">(USB newUsb)</span>&#123;<br>        newUsb.disconnect();<br>        <span class="hljs-built_in">this</span>.usb.disconnect();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<pre><code class="hljs">最后，我们需要用一个适配器类来模拟TypeC拓展坞，来连接USB接口和 Rj45 网线接口
</code></pre>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">class</span> <span class="hljs-title class_">TypeCAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Rj45Impl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">USB</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 先连接 TypeC</span><br>        System.out.println(<span class="hljs-string">&quot;TypeC 已连接&quot;</span>);<br>        <span class="hljs-comment">// 再连接 Rj45</span><br>        <span class="hljs-built_in">super</span>.connect();<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">disconnect</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 先断开 Rj45</span><br>        <span class="hljs-built_in">super</span>.disconnect();<br>        <span class="hljs-comment">// 再断开 TypeC</span><br>        System.out.println(<span class="hljs-string">&quot;TypeC 已断开&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>测试类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Computer</span> <span class="hljs-variable">computer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Computer</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">USBImpl</span>());<br>        <span class="hljs-type">USB</span> <span class="hljs-variable">typec</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TypeCAdapter</span>();<br>        computer.connect(typec);<br>        System.out.println(<span class="hljs-string">&quot;------------&quot;</span>);<br>        computer.discount(typec);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>运行结果：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs sql">USB 连接成功<span class="hljs-operator">!</span><br>TypeC 已连接<br>Rj45 连接成功<br><span class="hljs-comment">------------</span><br>Rj45 已断开.<br>TypeC 已断开<br>USB 已断开连接<br></code></pre></td></tr></table></figure>
<p>上述例子中，USB承担目标接口的角色，Rj45Impl承担适配者的角色，TypeC承担适配器的角色</p>
<h2 id="1-2-对象适配器"><a href="#1-2-对象适配器" class="headerlink" title="1.2 对象适配器"></a>1.2 对象适配器</h2><p>像之前那样的方式定义的适配器，虽然可以满足需求，但是由于Java是单继承的，适配器类失去了继承类的机会，这样可能会导致代码的耦合度变高，当继承的父类 Rj45Impl 发生变化时，那么适配器类也需要修改，这样不利于代码的维护。<br>对象适配器则是将适配者直接作为适配器类的成员变量，在实现方法时可以直接调用成员变量的方法，同时还支持继承其他的类，比类适配器好一些。<br>模板代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//目标接口</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Target</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">//适配者接口</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Adaptee</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">specificRequest</span><span class="hljs-params">()</span><br>    &#123;<br>        System.out.println(<span class="hljs-string">&quot;适配者中的业务代码被调用！&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ObjectAdapter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Target</span><br>&#123;<br>    <span class="hljs-keyword">private</span> Adaptee adaptee;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ObjectAdapter</span><span class="hljs-params">(Adaptee adaptee)</span><br>    &#123;<br>        <span class="hljs-built_in">this</span>.adaptee=adaptee;<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span><br>    &#123;<br>        adaptee.specificRequest();<br>    &#125;<br>&#125;<br><span class="hljs-comment">//客户端代码</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span><br>    &#123;<br>        System.out.println(<span class="hljs-string">&quot;对象适配器模式测试：&quot;</span>);<br>        <span class="hljs-type">Adaptee</span> <span class="hljs-variable">adaptee</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Adaptee</span>();<br>        <span class="hljs-type">Target</span> <span class="hljs-variable">target</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectAdapter</span>(adaptee);<br>        target.request();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">class</span> <span class="hljs-title class_">TypeCAdapter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">USB</span>&#123;<br>    <span class="hljs-keyword">private</span> Rj45 rj45;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">TypeCAdapter</span><span class="hljs-params">(Rj45 rj45)</span>&#123;<br>        <span class="hljs-built_in">this</span>.rj45 = rj45;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">connect</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 先连接 TypeC</span><br>        System.out.println(<span class="hljs-string">&quot;TypeC 已连接&quot;</span>);<br>        <span class="hljs-comment">// 再连接 Rj45</span><br>        rj45.connect();<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">disconnect</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 先断开 Rj45</span><br>        rj45.disconnect();<br>        <span class="hljs-comment">// 再断开 TypeC</span><br>        System.out.println(<span class="hljs-string">&quot;TypeC 已断开&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<pre><code class="hljs">不过这里需要注意，我们在构造方法里传入的参数是所谓的适配者，在测试的时候传入接口实现类即可：
</code></pre>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Computer</span> <span class="hljs-variable">computer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Computer</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">USBImpl</span>());<br>        <span class="hljs-type">USB</span> <span class="hljs-variable">typec</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TypeCAdapter</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Rj45Impl</span>());<br>        computer.connect(typec);<br>        System.out.println(<span class="hljs-string">&quot;------------&quot;</span>);<br>        computer.discount(typec);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>这里可以明显感觉到耦合度降低了，我们把需要适配的对象传入到对象适配器类中，这让代码看起来十分清晰。</p>
<h2 id="1-3-适用场景"><a href="#1-3-适用场景" class="headerlink" title="1.3 适用场景"></a>1.3 适用场景</h2><p>适配器模式 （Adapter）通常适用于以下场景：</p>
<ul>
<li>以前开发的系统存在满足新系统功能需求的类，但其接口跟新系统的接口不同</li>
<li>使用第三方提供的组件，但组件接口定义和自己要求的接口定义不同</li>
</ul>
<h1 id="二、桥接模式-Bridge"><a href="#二、桥接模式-Bridge" class="headerlink" title="二、桥接模式 Bridge"></a>二、桥接模式 Bridge</h1><hr>
<p>定义：将抽象与实现分离，使它们可以独立变化。它是用组合关系代替继承关系来实现，从而降低了抽象和实现这两个可变维度的耦合度。<br>结构:</p>
<ul>
<li>实现化角色（Implementor）：定义实现化角色的接口，供扩展抽象化角色调用</li>
<li>具体实现化角色（Concrete Implementor）：给出实现化角色的具体实现</li>
<li>抽象化角色（Abstraction）：定义抽象类，并包含一个对实现化对象的使用</li>
<li>扩展抽象化角色（Refined Abstraction）：是抽象化角色的子类，实现父类中的业务方法，并通过组合关系调用实现化角色中的业务方法</li>
</ul>
<p>优点：</p>
<ul>
<li>抽象与实现分离，扩展能力强</li>
<li>符合开闭原则</li>
<li>符合合成复用原则</li>
<li>其实现细节对用户透明</li>
</ul>
<p>缺点：</p>
<ul>
<li>聚合关系建立在抽象层，增加系统的理解难度与设计难度</li>
</ul>
<h2 id="2-1-模板代码"><a href="#2-1-模板代码" class="headerlink" title="2.1 模板代码"></a>2.1 模板代码</h2><p>模板代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 实现化角色</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Implementor</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">OperationImpl</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 具体实现化角色</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ConcreteImplementor</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Implementor</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">OperationImpl</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;具体实现化(Concrete Implementor) 角色被访问&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 抽象化角色</span><br><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Abstraction</span>&#123;<br>    <span class="hljs-keyword">protected</span> Implementor imple;<br>    <span class="hljs-keyword">protected</span> <span class="hljs-title function_">Abstraction</span><span class="hljs-params">(Implementor imple)</span>&#123;<br>        <span class="hljs-built_in">this</span>.imple = imple;<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">Operation</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 扩展抽象化角色</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">RefinedAbstraction</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Abstraction</span>&#123;<br>    <span class="hljs-keyword">protected</span> <span class="hljs-title function_">RefinedAbstraction</span><span class="hljs-params">(Implementor imple)</span>&#123;<br>        <span class="hljs-built_in">super</span>(imple);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">Operation</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;扩展抽象化 (Refined Abstraction) 角色被访问&quot;</span>);<br>        imple.OperationImpl();<br>    &#125;<br><br>&#125;<br><span class="hljs-comment">//客户端代码</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span><br>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span>&#123;<br>        <span class="hljs-type">Implementor</span> <span class="hljs-variable">imple</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConcreteImplementor</span>();<br>        <span class="hljs-type">Abstraction</span> <span class="hljs-variable">abs</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RefinedAbstraction</span>(imple);<br>        abs.Operation();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h2 id="2-2-应用实例"><a href="#2-2-应用实例" class="headerlink" title="2.2 应用实例"></a>2.2 应用实例</h2><p>【应用实例】购买不同种类不同杯的奶茶<br>未使用桥接模式的实现：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Tea</span> &#123; <span class="hljs-comment">// 奶茶</span><br>    String <span class="hljs-title function_">getType</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Size</span>&#123; <span class="hljs-comment">// 奶茶尺寸</span><br>    String <span class="hljs-title function_">getSize</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 甜奶茶</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">LargeSweetTea</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Tea</span>, Size&#123;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getType</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;甜奶茶&quot;</span>;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getSize</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;大杯&quot;</span>;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span>&#123;<br>        <span class="hljs-type">LargeSweetTea</span> <span class="hljs-variable">tea</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">LargeSweetTea</span>();<br>        System.out.println(<span class="hljs-string">&quot;请来一份: &quot;</span> + tea.getSize() + <span class="hljs-string">&quot; &quot;</span> + tea.getType());<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>像上面这样设计不方便扩展，不同尺寸、类型的奶茶都需要创建一个新的类。现在的问题就是维度太多，现在我们将奶茶的类型作为最基本的抽象类，然后对尺寸、配料属性进行桥接：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Size</span>&#123;<br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getSize</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">AbstractTea</span>&#123;<br>    <span class="hljs-keyword">protected</span> Size size;<br>    <span class="hljs-keyword">protected</span> <span class="hljs-title function_">AbstractTea</span><span class="hljs-params">(Size size)</span>&#123;<br>        <span class="hljs-built_in">this</span>.size = size;<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> String <span class="hljs-title function_">getType</span><span class="hljs-params">()</span>;   <span class="hljs-comment">// 具体类型由子类决定</span><br>&#125;<br><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RefineAbstractTea</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">AbstractTea</span>&#123;<br>    <span class="hljs-keyword">protected</span> <span class="hljs-title function_">RefineAbstractTea</span><span class="hljs-params">(Size size)</span> &#123;<br>        <span class="hljs-built_in">super</span>(size);<br>    &#125;<br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getSize</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-keyword">return</span> size.getSize();<br>    &#125;<br>&#125;<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Large</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Size</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getSize</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;大杯&quot;</span>;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SweetTea</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">RefineAbstractTea</span>&#123;<br><br>    <span class="hljs-keyword">protected</span> <span class="hljs-title function_">SweetTea</span><span class="hljs-params">(Size size)</span>&#123;<br>        <span class="hljs-built_in">super</span>(size);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getType</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;甜奶茶&quot;</span>;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span>&#123;<br>        <span class="hljs-type">SweetTea</span> <span class="hljs-variable">tea</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SweetTea</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Large</span>());<br>        System.out.println(tea.getType());<br>        System.out.println(tea.getSize());<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h2 id="2-3-使用场景"><a href="#2-3-使用场景" class="headerlink" title="2.3 使用场景"></a>2.3 使用场景</h2><ol>
<li>当一个类存在两个独立变化的维度，且这两个维度都需要进行扩展时</li>
<li>当一个系统不希望使用继承或因为多层次继承导致类的个数急剧增加时</li>
<li>当一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性时</li>
</ol>
<h1 id="三、-装饰器模式-Decorator"><a href="#三、-装饰器模式-Decorator" class="headerlink" title="三、 装饰器模式  Decorator"></a>三、 装饰器模式  Decorator</h1><hr>
<p>定义：在不改变现有对象结构的情况下，动态地给对象增加一些功能。</p>
<p>优点：</p>
<ul>
<li>装饰器比直接继承更灵活</li>
<li>通过使用装饰类和普通类之间的排列组合，可以实现不同的效果</li>
<li>装饰器模式完全遵守开闭原则</li>
</ul>
<p>缺点：</p>
<ul>
<li>增加许多子类，使用过多则容易增加程序复杂性</li>
</ul>
<h2 id="3-1-装饰器模式的结构与实现"><a href="#3-1-装饰器模式的结构与实现" class="headerlink" title="3.1 装饰器模式的结构与实现"></a>3.1 装饰器模式的结构与实现</h2><p>装饰器模式的主要角色：</p>
<ul>
<li>抽象构件 Component：定义一个抽象接口以规范准备接收附加责任的对象</li>
<li>具体构件 ConcreteComponent：实现抽象构件，通过装饰角色为其添加一些职责</li>
<li>抽象装饰 Decorator ：继承抽象构件的功能，并包含具体构件的实例，可通过其子类扩展具体构件的功能</li>
<li>具体装饰 ConcreteDecorator：实现抽象装饰的相关方法，并给具体构件对象添加的功能</li>
</ul>
<p>模板代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 装饰器模式</span><br><br><span class="hljs-comment">// 1. 抽象构件</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-comment">// 构件的操作</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 2. 具体构件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ConcreteComponent</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ConcreteComponent</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;具体构件创建成功&quot;</span>);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;具体构件执行完毕&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 3. 抽象装饰</span><br><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Decorator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">private</span> Component component;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Decorator</span><span class="hljs-params">(Component component)</span>&#123;<br>        <span class="hljs-built_in">this</span>.component = component;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        component.operation();<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 4. 具体装饰</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ConcreteDecorator</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Decorator</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ConcreteDecorator</span><span class="hljs-params">(Component component)</span> &#123;<br>        <span class="hljs-built_in">super</span>(component);<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">addedFunction</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;装饰器类的新函数执行完毕&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-built_in">super</span>.operation();<br>        addedFunction();<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Component</span> <span class="hljs-variable">oldC</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConcreteComponent</span>();<br>        <span class="hljs-type">Component</span> <span class="hljs-variable">newC</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConcreteDecorator</span>(oldC);<br>        oldC.operation();<br>        newC.operation();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>总结：</p>
<ul>
<li>所谓装饰，就是先抽象一层，即继承抽象类的接口，并存储这个接口。</li>
<li>接着继承装饰抽象类，添加需要增强的功能</li>
<li>这样装饰类和原先类拥有相同的实现接口，于是可通过相同的接口来调用方法</li>
</ul>
<h2 id="3-2-应用案例"><a href="#3-2-应用案例" class="headerlink" title="3.2 应用案例"></a>3.2 应用案例</h2><p>装饰器应用案例：普通人 -&gt; 超人</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 抽象构件</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span>&#123;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 普通人</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ConcretePerson</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Person</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ConcretePerson</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;普通人出现了&quot;</span>);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;[普通人]: 我每秒能跑2米&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 抽象装饰</span><br><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">DecoratorPerson</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Person</span>&#123;<br>    <span class="hljs-keyword">private</span> Person person;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">DecoratorPerson</span><span class="hljs-params">(Person person)</span>&#123;<br>        <span class="hljs-built_in">this</span>.person = person;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        person.run();<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 具体装饰</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SuperPerson</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">DecoratorPerson</span>&#123;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">SuperPerson</span><span class="hljs-params">(Person person)</span> &#123;<br>        <span class="hljs-built_in">super</span>(person);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;曾经的我: &quot;</span>);<br>        <span class="hljs-built_in">super</span>.run();<br>        System.out.println(<span class="hljs-string">&quot;现在的我: &quot;</span>);<br>        superManRun();<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">superManRun</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;[超人]: 我每秒能跑1000米&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Person</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConcretePerson</span>();<br>        person.run();<br>        <span class="hljs-type">Person</span> <span class="hljs-variable">superPerson</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SuperPerson</span>(person);<br>        superPerson.run();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>输出结果：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs sql">普通人出现了<br>[普通人]: 我每秒能跑<span class="hljs-number">2</span>米<br>曾经的我: <br>[普通人]: 我每秒能跑<span class="hljs-number">2</span>米<br>现在的我: <br>[超人]: 我每秒能跑<span class="hljs-number">1000</span>米<br></code></pre></td></tr></table></figure>
<h2 id="3-3-应用场景"><a href="#3-3-应用场景" class="headerlink" title="3.3 应用场景"></a>3.3 应用场景</h2><ul>
<li>当需要给一个类添加新的功能，又不能直接继承来扩充时</li>
<li>当需要通过现有的一些类进行排列组合而产生比较多的功能时</li>
<li>当对象的功能要求可动态添加也可动态地撤销时</li>
</ul>
<h1 id="四、组合模式-Composite-Pattern"><a href="#四、组合模式-Composite-Pattern" class="headerlink" title="四、组合模式 Composite Pattern"></a>四、组合模式 Composite Pattern</h1><hr>
<p>定义：组合模式有时称作 整体-部分 （Part-Whole）模式，是一种将对象组合成树状的层次结构的模式，用来表示“整体-部分”的关系，使用户对单个对象和组合对象具有一致的访问性。<br>优点：</p>
<ul>
<li>使得程序可一致性地处理单个对象和组合对象，无需区分是单个还是组合。</li>
<li>更容易在组合体内加入新的对象，客户端不会因为加入了新的对象而改变源代码，满足“开闭原则”</li>
</ul>
<p>缺点：</p>
<ul>
<li>设计较复杂，客户端需花时间理清类之间的层次关系</li>
<li>不容易限制容器中的构件</li>
<li>不容易用继承增加构件的新功能</li>
</ul>
<h2 id="4-1-组合模式的结构与实现"><a href="#4-1-组合模式的结构与实现" class="headerlink" title="4.1 组合模式的结构与实现"></a>4.1 组合模式的结构与实现</h2><ul>
<li>抽象构件（Component）：为树叶构件和树枝构件声明公共接口。</li>
<li>树叶构件（Leaf）：是组合中的叶节点对象，没有子节点，用于继承或实现抽象构件</li>
<li>树枝构件（Composite）角色 &#x2F; 中间构件：是组合中的分支支点对象，有子节点，用于继承和实现抽象的构件，作用是存储和管理子部件，通常包含 add()、remove()、getChild() 等方法。</li>
</ul>
<p>组合模式的分类：透明式 和 安全式</p>
<p>模板代码：<br>这里的模板以一颗二叉树为例<br>![](<a target="_blank" rel="noopener" href="https://img-blog.csdnimg.cn/img_convert/8063293f5e4e8466935f73cb388a7bd3.gif#clientId=u11d6e855-17f2-4&amp;crop=0&amp;crop=0&amp;crop=1&amp;crop=1&amp;from=paste&amp;id=uc873745e&amp;margin=[object">https://img-blog.csdnimg.cn/img_convert/8063293f5e4e8466935f73cb388a7bd3.gif#clientId=u11d6e855-17f2-4&amp;crop=0&amp;crop=0&amp;crop=1&amp;crop=1&amp;from=paste&amp;id=uc873745e&amp;margin=[object</a> Object]&amp;originHeight&#x3D;237&amp;originWidth&#x3D;250&amp;originalType&#x3D;url&amp;ratio&#x3D;1&amp;rotation&#x3D;0&amp;showTitle&#x3D;false&amp;status&#x3D;done&amp;style&#x3D;none&amp;taskId&#x3D;ud733fbf7-0cfd-4579-99eb-6abc668ad99&amp;title&#x3D;)<br><strong>1) 透明组合模式：耦合度较高</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> java.util.ArrayList;<br><span class="hljs-keyword">import</span> java.util.List;<br><br><span class="hljs-comment">// 透明式的组合模式</span><br><span class="hljs-comment">// 抽象构件</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(Component c)</span>&#123;&#125;<br>    <span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">remove</span><span class="hljs-params">(Component c)</span>&#123;&#125;<br>    <span class="hljs-keyword">default</span> Component <span class="hljs-title function_">getChild</span><span class="hljs-params">(<span class="hljs-type">int</span> i)</span>&#123;<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;&#125;<br>    <span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;&#125;<br>&#125;<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Leaf</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">private</span> String name;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Leaf</span><span class="hljs-params">(String name)</span>&#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;树叶: &quot;</span> + name + <span class="hljs-string">&quot; 被访问了&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 树枝构件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Composite</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">private</span> List&lt;Component&gt; children = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;Component&gt;();<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(Component c)</span> &#123;<br>        children.add(c);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">remove</span><span class="hljs-params">(Component c)</span> &#123;<br>        children.remove(c);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> Component <span class="hljs-title function_">getChild</span><span class="hljs-params">(<span class="hljs-type">int</span> i)</span> &#123;<br>        <span class="hljs-keyword">return</span> children.get(i);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">for</span> (Component child : children) &#123;<br>            child.operation();<br>        &#125;<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 树叶构件</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Composite</span> <span class="hljs-variable">c0</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Composite</span>();<br>        Composite c1= <span class="hljs-keyword">new</span> <span class="hljs-title class_">Composite</span>();<br>        <span class="hljs-type">Leaf</span> <span class="hljs-variable">leaf1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Leaf</span>(<span class="hljs-string">&quot;1&quot;</span>);<br>        <span class="hljs-type">Leaf</span> <span class="hljs-variable">leaf2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Leaf</span>(<span class="hljs-string">&quot;2&quot;</span>);<br>        <span class="hljs-type">Leaf</span> <span class="hljs-variable">leaf3</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Leaf</span>(<span class="hljs-string">&quot;3&quot;</span>);<br>        c0.add(leaf1);<br>        c0.add(c1);<br>        c1.add(leaf2);<br>        c1.add(leaf3);<br>        c0.operation();<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>2）安全组合模式</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> java.util.ArrayList;<br><span class="hljs-keyword">import</span> java.util.List;<br><br><span class="hljs-comment">// 透明式的组合模式</span><br><span class="hljs-comment">// 抽象构件</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Leaf</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">private</span> String name;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Leaf</span><span class="hljs-params">(String name)</span>&#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;树叶: &quot;</span> + name + <span class="hljs-string">&quot; 被访问了&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 树枝构件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Composite</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Component</span>&#123;<br>    <span class="hljs-keyword">private</span> List&lt;Component&gt; children = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;Component&gt;();<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(Component c)</span> &#123;<br>        children.add(c);<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">remove</span><span class="hljs-params">(Component c)</span> &#123;<br>        children.remove(c);<br>    &#125;<br>    <span class="hljs-keyword">public</span> Component <span class="hljs-title function_">getChild</span><span class="hljs-params">(<span class="hljs-type">int</span> i)</span> &#123;<br>        <span class="hljs-keyword">return</span> children.get(i);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">for</span> (Component child : children) &#123;<br>            child.operation();<br>        &#125;<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 树叶构件</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Composite</span> <span class="hljs-variable">c0</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Composite</span>();<br>        Composite c1= <span class="hljs-keyword">new</span> <span class="hljs-title class_">Composite</span>();<br>        <span class="hljs-type">Leaf</span> <span class="hljs-variable">leaf1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Leaf</span>(<span class="hljs-string">&quot;1&quot;</span>);<br>        <span class="hljs-type">Leaf</span> <span class="hljs-variable">leaf2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Leaf</span>(<span class="hljs-string">&quot;2&quot;</span>);<br>        <span class="hljs-type">Leaf</span> <span class="hljs-variable">leaf3</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Leaf</span>(<span class="hljs-string">&quot;3&quot;</span>);<br>        c0.add(leaf1);<br>        c0.add(c1);<br>        c1.add(leaf2);<br>        c1.add(leaf3);<br>        c0.operation();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="4-2-应用案例"><a href="#4-2-应用案例" class="headerlink" title="4.2 应用案例"></a>4.2 应用案例</h2><p>使用安全式的组合模式实现：购物车</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> java.util.ArrayList;<br><span class="hljs-keyword">import</span> java.util.List;<br><br><span class="hljs-comment">// 组合模式</span><br><span class="hljs-comment">// 抽象构件: 总结</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">SummaryComponent</span>&#123;<br>    <span class="hljs-type">float</span> <span class="hljs-title function_">summary</span><span class="hljs-params">()</span>;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">show</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 树叶构件: 商品</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">GoodsLeaf</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">SummaryComponent</span>&#123;<br>    <span class="hljs-keyword">private</span> String name;    <span class="hljs-comment">// 商品名称</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> count;      <span class="hljs-comment">// 商品数量</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-type">float</span> price;    <span class="hljs-comment">// 商品单价</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">GoodsLeaf</span><span class="hljs-params">(String name, <span class="hljs-type">int</span> count, <span class="hljs-type">float</span> price)</span>&#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>        <span class="hljs-built_in">this</span>.count = count;<br>        <span class="hljs-built_in">this</span>.price = price;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">float</span> <span class="hljs-title function_">summary</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> price * count;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">show</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<br>                String.format(<span class="hljs-string">&quot;[%s] (数量: %d 件, 单价: ￥ %.2f)&quot;</span>, name, count, price)<br>        );<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 树枝构件: 购物篮</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BasketComposite</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">SummaryComponent</span>&#123;<br>    List&lt;SummaryComponent&gt; children = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(SummaryComponent c)</span>&#123;<br>        children.add(c);<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">remove</span><span class="hljs-params">(SummaryComponent c)</span>&#123;<br>        children.remove(c);<br>    &#125;<br>    <span class="hljs-keyword">public</span> SummaryComponent <span class="hljs-title function_">getChild</span><span class="hljs-params">(<span class="hljs-type">int</span> i)</span>&#123;<br>        <span class="hljs-keyword">return</span> children.get(i);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">float</span> <span class="hljs-title function_">summary</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-type">float</span> <span class="hljs-variable">total</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;<br>        <span class="hljs-keyword">for</span> (SummaryComponent child : children) &#123;<br>            total += child.summary();<br>        &#125;<br>        <span class="hljs-keyword">return</span> total;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">show</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">for</span> (SummaryComponent child : children) &#123;<br>            child.show();<br>        &#125;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br><br>        <span class="hljs-type">GoodsLeaf</span> <span class="hljs-variable">g1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">GoodsLeaf</span>(<span class="hljs-string">&quot;洗衣液&quot;</span>, <span class="hljs-number">100</span>, <span class="hljs-number">19.9f</span>);<br>        <span class="hljs-type">GoodsLeaf</span> <span class="hljs-variable">g2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">GoodsLeaf</span>(<span class="hljs-string">&quot;帽子&quot;</span>, <span class="hljs-number">10</span>, <span class="hljs-number">29.9f</span>);<br>        <span class="hljs-type">GoodsLeaf</span> <span class="hljs-variable">g3</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">GoodsLeaf</span>(<span class="hljs-string">&quot;枕头&quot;</span>, <span class="hljs-number">30</span>, <span class="hljs-number">10.0f</span>);<br><br>        <span class="hljs-type">BasketComposite</span> <span class="hljs-variable">bc</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BasketComposite</span>();<br>        bc.add(g1);<br>        bc.add(g2);<br>        bc.add(g3);<br>        System.out.println(<span class="hljs-string">&quot;======购物篮清单=====&quot;</span>);<br>        bc.show();<br>        System.out.println(<span class="hljs-string">&quot;总价: &quot;</span> + bc.summary() + <span class="hljs-string">&quot; 元&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>运行结果：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span>购物篮清单<span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span><br>[洗衣液] (数量: <span class="hljs-number">100</span> 件, 单价: ￥ <span class="hljs-number">19.90</span>)<br>[帽子] (数量: <span class="hljs-number">10</span> 件, 单价: ￥ <span class="hljs-number">29.90</span>)<br>[枕头] (数量: <span class="hljs-number">30</span> 件, 单价: ￥ <span class="hljs-number">10.00</span>)<br>总价: <span class="hljs-number">2589.0</span> 元<br></code></pre></td></tr></table></figure>
<h2 id="4-3-应用场景"><a href="#4-3-应用场景" class="headerlink" title="4.3 应用场景"></a>4.3 应用场景</h2><ul>
<li>需表示对象整体与部分层次结构的场合</li>
<li>要求对用户隐藏组合对象与单个对象的不同，用户可用统一的接口使用组合结构中的所有对象的场合</li>
</ul>
<h1 id="五、代理模式"><a href="#五、代理模式" class="headerlink" title="五、代理模式"></a>五、代理模式</h1><hr>
<p>代理模式定义：由于某种原因需要对某对象提供一个代理以控制对该对象的访问。这时，访问对象不适合或不能直接引用目标对象，代理对象则作为访问对象和目标对象之间的中介。</p>
<p>代理模式与装饰器模式对比</p>
<ul>
<li>装饰器模式，装饰器和被装饰者都实现同一个接口或抽象类</li>
<li>代理模型，代理类和被代理类都实现同一个接口或抽象类</li>
</ul>
<p>结构上没有区别，但作用各不相同。<br>装饰器模式强调的是增强自身，在被装饰后能在被增强的类上使用增强后的功能。<br>代理模式是强调被增强，添加与本身业务关系不大的事情，比如日志记录、设置缓存等。<br>这两者的差距主要在于思想。<br>分类：</p>
<ul>
<li>静态代理：由程序员创建代理类或特定工具自动生成源代码，对其进行编译，在程序运行前代理类的 字节码文件就已经存在</li>
<li>动态代理：在程序运行时，运行反射机制动态创建而成</li>
</ul>
<p>优点：</p>
<ul>
<li>代理模式可在客户端和目标对象之间起到一个中介作用和保护目标对象的作用</li>
<li>代理对象可以扩展目标对象的功能</li>
<li>代理模式能将客户端与目标独对象分离，在一定程度上降低系统的耦合度，增加了程序的可扩展性</li>
</ul>
<p>缺点：</p>
<ul>
<li>代理模式会导致系统设计增加更多的类</li>
<li>在客户端和目标对象之间增加一个代理对象，会造成请求代理速度变慢</li>
<li>【静态代理】增加了系统的复杂度。</li>
</ul>
<p>主要结构：<br>1）Subject， 抽象主体类，通过接口或抽象类声明真实主体和对象实现的业务方法<br>2）Real Subject， 真实主体类，实现了抽象主体中的具体业务，是代理对象所代表的真实对象，是最终要引用的对象<br>3）Proxy，代理类，提供了与真实主体相同的接口，其内部含有对真实主体的引用，可以访问、控制或扩展真实主体的功能</p>
<h2 id="5-1-模板代码"><a href="#5-1-模板代码" class="headerlink" title="5.1 模板代码"></a>5.1 模板代码</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 静态代理模式</span><br><span class="hljs-comment">// 抽象主体</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Subject</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 真实主体</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">RealSubject</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Subject</span>&#123;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;访问真实主体的方法&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 代理类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TestProxy</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Subject</span>&#123;<br>    <span class="hljs-keyword">private</span> RealSubject realSubject;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">request</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 懒汉式</span><br>        <span class="hljs-keyword">if</span>(realSubject == <span class="hljs-literal">null</span>)&#123;<br>            realSubject = <span class="hljs-keyword">new</span> <span class="hljs-title class_">RealSubject</span>();<br>        &#125;<br>        preRequest();<br>        realSubject.request();<br>        postRequest();<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">preRequest</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;访问真实主体前的操作.&quot;</span>);<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">postRequest</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;访问真实主体后的操作.&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Subject</span> <span class="hljs-variable">subject</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TestProxy</span>();<br>        subject.request();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="5-2-动态代理"><a href="#5-2-动态代理" class="headerlink" title="5.2 动态代理"></a>5.2 动态代理</h2><p>【例1】使用 JDK 实现代理，缺点：不支持代理抽象类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> java.lang.reflect.InvocationHandler;<br><span class="hljs-keyword">import</span> java.lang.reflect.Method;<br><span class="hljs-keyword">import</span> java.lang.reflect.Proxy;<br><br><span class="hljs-comment">// 抽象主体</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Subject</span>&#123;<br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">request</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 具体化主体</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">RealSubject</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Subject</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">request</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;访问真实主体&quot;</span>;<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 代理</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TestProxy</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">InvocationHandler</span>&#123;<br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Object object;    <span class="hljs-comment">// 被代理的对象</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">TestProxy</span><span class="hljs-params">(Object object)</span>&#123;<br>        <span class="hljs-built_in">this</span>.object = object;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">invoke</span><span class="hljs-params">(Object proxy, Method method, Object[] args)</span> <span class="hljs-keyword">throws</span> Throwable &#123;<br>        System.out.println(<span class="hljs-string">&quot;代理的对象: &quot;</span> + proxy.getClass());<br>        <span class="hljs-type">Object</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> method.invoke(object, args);<br>        System.out.println(<span class="hljs-string">&quot;方法调用完成, 返回值为: &quot;</span> + result);<br>        <span class="hljs-keyword">return</span> result;  <span class="hljs-comment">// 返回返回值</span><br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Subject</span> <span class="hljs-variable">subject</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RealSubject</span>();<br>        <span class="hljs-type">TestProxy</span> <span class="hljs-variable">proxy</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TestProxy</span>(subject);<br>        <span class="hljs-type">Subject</span> <span class="hljs-variable">proxySubject</span> <span class="hljs-operator">=</span> (Subject) Proxy.newProxyInstance(<br>                subject.getClass().getClassLoader(),<br>                subject.getClass().getInterfaces(),<br>                proxy);<br>        proxySubject.request();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>【例2】使用 cglib框架实现代理<br>截至2022&#x2F;07&#x2F;15，cglib框架于2019年停止更新</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>cglib<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>cglib<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.3.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">import</span> net.sf.cglib.proxy.Enhancer;<br><span class="hljs-keyword">import</span> net.sf.cglib.proxy.MethodInterceptor;<br><span class="hljs-keyword">import</span> net.sf.cglib.proxy.MethodProxy;<br><br><span class="hljs-keyword">import</span> java.lang.reflect.InvocationHandler;<br><span class="hljs-keyword">import</span> java.lang.reflect.Method;<br><span class="hljs-keyword">import</span> java.lang.reflect.Proxy;<br><br><span class="hljs-comment">// 抽象主体</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Subject</span>&#123;<br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">request</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">// 具体化主体</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">RealSubject</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Subject</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">request</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;访问真实主体&quot;</span>;<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 代理</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TestProxy</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">MethodInterceptor</span>&#123;<br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Object target;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">TestProxy</span><span class="hljs-params">(Object target)</span>&#123;<br>        <span class="hljs-built_in">this</span>.target = target;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">intercept</span><span class="hljs-params">(Object o, Method method, Object[] args, MethodProxy methodProxy)</span> <span class="hljs-keyword">throws</span> Throwable &#123;<br>        System.out.println(<span class="hljs-string">&quot;CGlib代理的对象为:&quot;</span> + o.getClass());<br>        <span class="hljs-type">Object</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> method.invoke(target, args);<br>        System.out.println(method.getName() + <span class="hljs-string">&quot;方法执行结果:&quot;</span> + result);<br>        <span class="hljs-keyword">return</span> result;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Subject</span> <span class="hljs-variable">subject</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RealSubject</span>();<br>        <span class="hljs-type">Enhancer</span> <span class="hljs-variable">enhancer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Enhancer</span>();         <span class="hljs-comment">// CGlib 增强器</span><br>        enhancer.setSuperclass(RealSubject.class);  <span class="hljs-comment">// 设置要代理的对象，只需要字节码，不固定是接口或抽象类</span><br>        enhancer.setCallback(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TestProxy</span>(subject));   <span class="hljs-comment">// 设置代理类</span><br>        <span class="hljs-type">RealSubject</span> <span class="hljs-variable">proxy</span> <span class="hljs-operator">=</span> (RealSubject) enhancer.create(); <span class="hljs-comment">// 创建增强器</span><br>        proxy.request();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h2 id="5-3-应用场景"><a href="#5-3-应用场景" class="headerlink" title="5.3 应用场景"></a>5.3 应用场景</h2><p>代理模式的目的：1）保护目标对象，2）增强目标对象<br>代理模式的应用场景：<br>1） 远程代理，为了隐藏目标对象存在于不同地址空间，方便客户端访问。例如，用户申请网盘空间时，会在用户的文件系统里建立虚拟的硬盘，用户访问这个虚拟硬盘实际访问的是网盘空间<br>2）虚拟代理，解决要创建的目标对象开销很大的问题，例如，下载一副很大的图片需很长时间，因某种计算比较复杂而短时间内无法完成，这时可先用小比例的虚拟代理替换真实对象，减少用户对服务器慢的感觉<br>3）安全代理，控制不同身份的用户对真实对象的访问权限<br>4）延迟加载，为了提高系统性能，延迟对目标的加载<br>…</p>
<h1 id="六、外观模式-Facade"><a href="#六、外观模式-Facade" class="headerlink" title="六、外观模式 Facade"></a>六、外观模式 Facade</h1><hr>
<p>定义：外观（Facade）模式又称门面模式，是一种通过为多个复杂的子系统提供一个一致的接口，而使这些子系统更加容易被访问的模式。</p>
<p>是“迪米特法则”（最少知识原则）的典型应用</p>
<p>优点：</p>
<ul>
<li>降低子系统与客户端之间的耦合度，使得子系统变化不会影响到用户类</li>
<li>对用户屏蔽了子系统组件，减少了用户处理的对象个数，简化子系统的使用</li>
<li>降低大型软件系统中的编译依赖性，简化了系统在不同平台之间的移植过程</li>
</ul>
<p>缺点：</p>
<ul>
<li>不能很好的限制客户使用子系统类，容易带来未知的风险</li>
<li>增加子系统可能需要修改外观类或客户端的源代码，违背了”开闭原则”</li>
</ul>
<h2 id="6-1-主要组成"><a href="#6-1-主要组成" class="headerlink" title="6.1 主要组成"></a>6.1 主要组成</h2><p>外观模式的结构比较简单，主要定义了一个高层接口，包含了对各个子系统的引用。<br>1） 外观角色，Facade，为多个子系统对外提供一个共同的接口<br>2）子系统角色，SubSystem，实现系统的部分功能，用户可以通过外观访问。<br>3）用户角色，Client，通过一个外观角色访问各个子系统的功能</p>
<h2 id="6-2-模板代码"><a href="#6-2-模板代码" class="headerlink" title="6.2 模板代码"></a>6.2 模板代码</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 外观模式</span><br><span class="hljs-comment">// 子系统角色1</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SubSystem01</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">method1</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;子系统01的method1() 被调用&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 子系统角色2</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SubSystem02</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">method2</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;子系统02的method2() 被调用&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 子系统角色3</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SubSystem03</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">method3</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;子系统03的method3() 被调用&quot;</span>);<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 外观角色</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Facade</span>&#123;<br>    <span class="hljs-comment">// 单例模式: 饿汉式</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-type">SubSystem01</span> <span class="hljs-variable">obj1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SubSystem01</span>();<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">SubSystem02</span> <span class="hljs-variable">obj2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SubSystem02</span>();<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">SubSystem03</span> <span class="hljs-variable">obj3</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SubSystem03</span>();<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">method</span><span class="hljs-params">()</span>&#123;<br>        obj1.method1();<br>        obj2.method2();<br>        obj3.method3();<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Facade</span> <span class="hljs-variable">f</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Facade</span>();<br>        f.method();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h2 id="6-3-应用场景"><a href="#6-3-应用场景" class="headerlink" title="6.3 应用场景"></a>6.3 应用场景</h2><ul>
<li>对分层结构系统构建时，使用外观模式定义子系统中每层的入口点可简化子系统之间的依赖关系</li>
<li>当一个复杂系统的子系统很多时，外观模式可以为系统设计一个简单的接口供外界访问</li>
<li>当客户端与多个子系统之间存在很大的联系时，引入外观模式可将它们分离，从而提高子系统的独立性和可移植性</li>
</ul>
<h1 id="七、享元模式-Flyweight"><a href="#七、享元模式-Flyweight" class="headerlink" title="七、享元模式 Flyweight"></a>七、享元模式 Flyweight</h1><hr>
<p>定义：享元模式即运用共享技术来有效地支持细粒度较高对象的复用，是创建型工厂方法模式的一个改进机制。</p>
<p>与单例模式比较：<br><strong>共同点：</strong>避免重复创建对象<br><strong>不同点：</strong></p>
<ul>
<li>单例模式一个类只有唯一的实例，而享元模式可以有多个实例，只是通过一个共享容器来存储不同的对象。</li>
<li>单例模式强调减少实例化提升性能，适用于需频繁创建和销毁实例的对象 或 实例化对象耗资源的场景，比如数据库连接池、多线程的线程池。而享元模式则强调共享相同的对象或对象属性，节约内存使用空间</li>
</ul>
<p><strong>优点：</strong></p>
<ul>
<li>相同对象只需保存一份，降低了系统中对象的个数，从而降低内存压力</li>
</ul>
<p><strong>缺点：</strong></p>
<ul>
<li>为了使对象可共享，需将一些不能共享的状态外部化，增加程序的复杂性</li>
<li>读取享元模式的外部状态会使运行时间稍微边长</li>
</ul>
<h2 id="7-1-主要组成"><a href="#7-1-主要组成" class="headerlink" title="7.1 主要组成"></a>7.1 主要组成</h2><p>1）抽象享元角色 , Flyweight, 是所有的具有享元类的基类，为具体享元规范需要实现的公共接口，非享元的外部状态以参数的形式通过方法传入。<br>2）具体享元角色，Concrete Flyweight，实现抽象享元角色中所规定的接口<br>3）非享元角色，Unshareable Flyweight，不可以共享的外部状态，以参数的形式注入具体享元的相关方法中<br>4）享元工厂角色，Flyweight Factory，负责创建和管理享元角色，若存在则直接提供，不存在则创建新的享受元对象</p>
<h2 id="7-2-模板代码"><a href="#7-2-模板代码" class="headerlink" title="7.2 模板代码"></a>7.2 模板代码</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// 享元模式</span><br><br><span class="hljs-keyword">import</span> java.util.HashMap;<br><span class="hljs-keyword">import</span> java.util.Map;<br><br><span class="hljs-comment">// 非享元角色</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">UnsharableConcreteFlyweight</span>&#123;<br>    <span class="hljs-keyword">private</span> String info;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">UnsharableConcreteFlyweight</span><span class="hljs-params">(String info)</span>&#123;<br>        <span class="hljs-built_in">this</span>.info = info;<br>    &#125;<br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getInfo</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.info;<br>    &#125;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setInfo</span><span class="hljs-params">(String info)</span>&#123;<br>        <span class="hljs-built_in">this</span>.info = info;<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 抽象享元角色</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Flyweight</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">(UnsharableConcreteFlyweight state)</span>;<br>&#125;<br><span class="hljs-comment">// 具体享元角色</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ConcreteFlyweight</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Flyweight</span>&#123;<br>    <span class="hljs-keyword">private</span> String key;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ConcreteFlyweight</span><span class="hljs-params">(String key)</span>&#123;<br>        <span class="hljs-built_in">this</span>.key = key;<br>        System.out.println(<span class="hljs-string">&quot;具体享元: &quot;</span> + key + <span class="hljs-string">&quot; 被创建!&quot;</span>);<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">operation</span><span class="hljs-params">(UnsharableConcreteFlyweight state)</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;具体享元:&quot;</span> + key + <span class="hljs-string">&quot; 被调用&quot;</span>);<br>        System.out.println(<span class="hljs-string">&quot;非享元信息是: &quot;</span> + state.getInfo());<br>    &#125;<br>&#125;<br><span class="hljs-comment">// 享元工厂角色</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">FlyweightFactory</span>&#123;<br>    Map&lt;String, Flyweight&gt; flyweights = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;String ,Flyweight&gt;();<br><br>    <span class="hljs-keyword">public</span> Flyweight <span class="hljs-title function_">getFlyweight</span><span class="hljs-params">(String key)</span>&#123;<br>        <span class="hljs-type">Flyweight</span> <span class="hljs-variable">flyweight</span> <span class="hljs-operator">=</span> flyweights.get(key);<br>        <span class="hljs-keyword">if</span>(flyweight != <span class="hljs-literal">null</span>)&#123;<br>            System.out.println(<span class="hljs-string">&quot;具体享元: &quot;</span> + key + <span class="hljs-string">&quot; 被成功获取 --&gt;&quot;</span> + flyweight);<br>        &#125; <span class="hljs-keyword">else</span>&#123;<br>            flyweight = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConcreteFlyweight</span>(key);<br>            flyweights.put(key, flyweight);<br>            System.out.println(<span class="hljs-string">&quot;具体享元: &quot;</span> + key +<span class="hljs-string">&quot; 创建成功!&quot;</span>);<br>        &#125;<br>        <span class="hljs-keyword">return</span> flyweight;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Demo</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">FlyweightFactory</span> <span class="hljs-variable">factory</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FlyweightFactory</span>();<br>        <span class="hljs-type">Flyweight</span> <span class="hljs-variable">a0</span> <span class="hljs-operator">=</span> factory.getFlyweight(<span class="hljs-string">&quot;a&quot;</span>);<br>        <span class="hljs-type">Flyweight</span> <span class="hljs-variable">a1</span> <span class="hljs-operator">=</span> factory.getFlyweight(<span class="hljs-string">&quot;a&quot;</span>);<br>        <span class="hljs-type">Flyweight</span> <span class="hljs-variable">b0</span> <span class="hljs-operator">=</span> factory.getFlyweight(<span class="hljs-string">&quot;b&quot;</span>);<br>        <span class="hljs-type">Flyweight</span> <span class="hljs-variable">b1</span> <span class="hljs-operator">=</span> factory.getFlyweight(<span class="hljs-string">&quot;b&quot;</span>);<br>        <span class="hljs-type">Flyweight</span> <span class="hljs-variable">b2</span> <span class="hljs-operator">=</span> factory.getFlyweight(<span class="hljs-string">&quot;b&quot;</span>);<br>        a0.operation(<span class="hljs-keyword">new</span> <span class="hljs-title class_">UnsharableConcreteFlyweight</span>(<span class="hljs-string">&quot;第1次调用a&quot;</span>));<br>        a1.operation(<span class="hljs-keyword">new</span> <span class="hljs-title class_">UnsharableConcreteFlyweight</span>(<span class="hljs-string">&quot;第2次调用a&quot;</span>));<br>        b0.operation(<span class="hljs-keyword">new</span> <span class="hljs-title class_">UnsharableConcreteFlyweight</span>(<span class="hljs-string">&quot;第1次调用b&quot;</span>));<br>        b1.operation(<span class="hljs-keyword">new</span> <span class="hljs-title class_">UnsharableConcreteFlyweight</span>(<span class="hljs-string">&quot;第2次调用b&quot;</span>));<br>        b2.operation(<span class="hljs-keyword">new</span> <span class="hljs-title class_">UnsharableConcreteFlyweight</span>(<span class="hljs-string">&quot;第3次调用b&quot;</span>));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="7-3-应用场景"><a href="#7-3-应用场景" class="headerlink" title="7.3 应用场景"></a>7.3 应用场景</h2><p>1） 当系统中需同一组信息时，可把信息封装到一个对象中，然后对该对象进行缓存，避免同一对象多次创建，降低内存空间的消耗</p>
<p>2）适用于大部分对象可按照内部状态进行分组，且可将不同部分外部化，这样每组只需保存一个内部状态</p>
<p>3）由于享元模式需额外维护一个保存享元的数据结构，所以应当在有足够多的享元示例时再使用享受模式。</p>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" class="category-chain-item">设计模式</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">#设计模式</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>设计模式 笔记2 _ 七个结构型模式 _ 适配器模式 _ 桥接模式 _ 装饰器模式 _ 组合模式 _ 代理模式_ 外观模式 _ 享元模式 _模板代码、优缺点、应用场景总结 _ 基于Java实现</div>
      <div>http://example.com/2022/08/11/设计模式 笔记2 _ 七个结构型模式 _ 适配器模式 _ 桥接模式 _ 装饰器模式 _ 组合模式 _ 代理模式_ 外观模式 _ 享元模式 _模板代码、优缺点、应用场景总结 _ 基于Java实现/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>John Doe</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2022年8月11日</div>
        </div>
      
      
      <div class="license-meta-item">
        <div>许可协议</div>
        <div>
          
            
            
              <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
              <span class="hint--top hint--rounded" aria-label="BY - 署名">
                <i class="iconfont icon-by"></i>
              </span>
              </a>
            
          
        </div>
      </div>
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2022/08/16/JavaScript%20%E7%AC%94%E8%AE%B01%20ES6%20%E6%96%B0%E7%89%B9%E6%80%A7%20_%20%E8%A7%A3%E6%9E%84%E8%B5%8B%E5%80%BC%E3%80%81%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2%E3%80%81Symbol%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E3%80%81Promise%E3%80%81%E6%A8%A1%E5%9D%97%E5%8C%96/" title="JavaScript 笔记1 ES6 新特性 _ 解构赋值、模板字符串、Symbol数据类型、Promise、模块化">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">JavaScript 笔记1 ES6 新特性 _ 解构赋值、模板字符串、Symbol数据类型、Promise、模块化</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2022/08/04/Python%20Web%20%E5%BC%80%E5%8F%91%20_%20Flask%20%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E7%94%A8%E6%88%B7%E6%B3%A8%E5%86%8C%E3%80%81%E7%99%BB%E5%BD%95%E3%80%81%E6%B3%A8%E9%94%80%E3%80%81%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3%20_%20%E5%88%9D%E5%AD%A6%E8%80%85%E6%A1%88%E4%BE%8B%20_%20%E7%AE%80%E5%8D%95%E5%B0%81%E8%A3%85%E5%93%8D%E5%BA%94%E6%95%B0%E6%8D%AE%20_%20%E4%BD%BF%E7%94%A8%20Postman%20%E8%BF%9B%E8%A1%8C%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95/" title="Python Web 开发 _ Flask 简单实现用户注册、登录、注销、查询接口 _ 初学者案例 _ 简单封装响应数据 _ 使用 Postman 进行接口测试.">
                        <span class="hidden-mobile">Python Web 开发 _ Flask 简单实现用户注册、登录、注销、查询接口 _ 初学者案例 _ 简单封装响应数据 _ 使用 Postman 进行接口测试.</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      headingSelector : CONFIG.toc.headingSelector || 'h1,h2,h3,h4,h5,h6',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      collapseDepth   : CONFIG.toc.collapseDepth || 0,
      scrollSmooth    : true,
      headingsOffset  : -boardTop
    });
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.10/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
